package com.sz.biz.logistics.base.service.impl;

import com.sz.biz.common.base.dto.AreaDto;
import com.sz.biz.common.base.dto.CityModel;
import com.sz.biz.common.base.dto.CountryDto;
import com.sz.biz.common.base.entity.Country;
import com.sz.biz.common.base.service.AreaManager;
import com.sz.biz.common.constants.ErrorCodes;
import com.sz.biz.common.constants.LanguageCode;
import com.sz.biz.common.constants.ModuleNames;
import com.sz.biz.logistics.base.dto.PortDto;
import com.sz.biz.logistics.base.dto.TransportModel;
import com.sz.biz.logistics.base.entity.Port;
import com.sz.biz.logistics.base.service.PortService;
import com.sz.common.base.constants.UserActions;
import com.sz.common.base.dao.DaoSupport;
import com.sz.common.base.dao.ParamData;
import com.sz.common.base.dto.I18nDto;
import com.sz.common.base.dto.QResultDto;
import com.sz.common.base.dto.QueryParams;
import com.sz.common.base.dto.ResultDto;
import com.sz.common.base.exception.Exceptions;
import com.sz.common.base.service.AbstractService;
import com.sz.common.base.utils.CollectionUtils;
import com.sz.common.base.utils.EntityUtils;
import com.sz.common.base.utils.StringUtils;
import com.sz.common.core.service.PrincipalLogUtils;
import com.sz.common.core.service.PrincipalUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.util.*;

/**
 * Function: 港口portServiceImpl <br>
 * Author: penghui.zheng <br>
 * Date: 2017-5-16 15:41:00
 */
@Service("portService")
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public class PortServiceImpl extends AbstractService implements PortService {

    @Resource(name = "daoSupport")
    private DaoSupport dao;

    @Autowired
    private AreaManager areaManager;

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public int savePort(PortDto portDto) {
        Port port = new Port();
        EntityUtils.copyPropertiesIgnoreNull(portDto, port);
        // 检查数据不能重复
        Map<String, Object> map = new HashMap<>();
        map.put("code", port.getCode());
        Port portExist = (Port) dao.findForObject("PortMapper.checkCode", map);
        if (portExist != null) {
            throw Exceptions.bizException(ErrorCodes.ERROR_BIZ_PORT_CODE_EXIST);
        }
        dao.save("PortMapper.insertSelective", port);
        // 保存操作日志
        Map<String, Object> dataBackup = new HashMap<>();
        dataBackup.put("ADD_PORT", port);
        PrincipalLogUtils.addOperationLog(ModuleNames.BIZ, ModuleNames.BIZ_PORT, UserActions.ADD, "新建港口", dataBackup);
        return port.getId();
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public int updatePort(PortDto portDto) {
        Port port = new Port();
        EntityUtils.copyPropertiesIgnoreNull(portDto, port);
        // 检查数据不能重复
        Map<String, Object> map = new HashMap<>();
        map.put("code", port.getCode());
        map.put("id", port.getId());
        Port portExist = (Port) dao.findForObject("PortMapper.checkCode", map);
        if (portExist != null) {
            throw Exceptions.bizException(ErrorCodes.ERROR_BIZ_PORT_CODE_EXIST);
        }
        dao.update("PortMapper.updateByPortId", port);
        // 保存操作日志
        Map<String, Object> dataBackup = new HashMap<>();
        dataBackup.put("UPDATE_PORT", port);
        PrincipalLogUtils.addOperationLog(ModuleNames.BIZ, ModuleNames.BIZ_PORT, UserActions.UPDATE, "修改港口",
                dataBackup);
        return port.getId();
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public void deleteByPortIds(List<Integer> ids) {
        dao.update("PortMapper.deleteByPortIds", ids);
        // 保存操作日志
        Map<String, Object> dataBackup = new HashMap<>();
        dataBackup.put("DELETE_PORT", ids);
        PrincipalLogUtils.addOperationLog(ModuleNames.BIZ, ModuleNames.BIZ_PORT, UserActions.DELETE, "删除港口",
                dataBackup);

    }

    @Override
    public PortDto findByPortId(int id) {
        ParamData pd = new ParamData();
        List<Country> allList = dao.findForList("CountryMapper" + ".findArea", pd, Country.class);
        pd.put("id", id);
        PortDto portDto = (PortDto) dao.findForObject("PortMapper.findByPortId", pd);
        List<I18nDto> i18n = new ArrayList<I18nDto>();
        if (portDto != null && portDto.getId() != null) {
            int refId = portDto.getId();
            ParamData pdi18n = new ParamData();
            pdi18n.put("refId", refId);
            i18n = dao.findForList("PortMapper" + ".findPortI18n", pdi18n, I18nDto.class);

            for (Country country : allList) {
                if (portDto.getCountryId().equals(country.getFigureCode())) {
                    portDto.setCountryName(country.getName());
                }
            }
            if (portDto.getCityId() != null && !"".equals(portDto.getCityId())) {
                portDto.setCityName(getCityName(portDto.getCountryId(), portDto.getCityId()));
            }

        }
        if (portDto != null) {//TODO whp修改20170817
            portDto.setI18n(i18n);
        }
        return portDto;
    }

    @Override
    public Port findShortById(int id) {
        Port port = null;
        if (id > 0) {
            List<Port> portList = this.findShortById(Arrays.asList(id));
            if (!CollectionUtils.isEmpty(portList)) {
                port = portList.get(0);
            }
        }
        return port;
    }

    @Override
    public List<Port> findShortById(List<Integer> ids) {
        List<Port> portList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(ids)) {
            ParamData pd = new ParamData();
            pd.put("ids", ids);
            portList = dao.findForList("PortMapper.findShortById", pd, Port.class);
        }
        return portList;
    }

    private String getCityName(String countryName, String cityId) {
        String cityName = "";
        ParamData pdArea = new ParamData();
        pdArea.put("id", cityId);
        if (LanguageCode.CN_UPPER.equals(countryName)) {
            AreaDto areaCnDto = (AreaDto) dao.findForObject("AreaCNMapper.findByAreaId", pdArea);
            cityName = areaCnDto.getName();
        } else {
            AreaDto areaDto = (AreaDto) dao.findForObject("AreaMapper.findByAreaId", pdArea);
            cityName = areaDto.getName();
        }
        return cityName;
    }

    @Override
    public ResultDto findPortList(QueryParams params) {
        String language = PrincipalUtils.getLocalLanguage();
        params.setLanguage(language);
        ParamData pd = this.convertQueryParams(params);
        ParamData pdCountry = new ParamData();
        List<Country> allList = dao.findForList("CountryMapper" + ".findArea", pdCountry, Country.class);
        // 调用方法查询数据
        List<PortDto> list = dao.findForList("PortMapper" + ".portListPage", pd, PortDto.class);
        for (PortDto portDto : list) {
            for (Country country : allList) {
                if (portDto.getCountryId().equals(country.getFigureCode())) {
                    portDto.setCountryName(country.getName());
                }
            }
            ParamData pdArea = new ParamData();
            if (portDto.getCityId() != null && !"".equals(portDto.getCityId())) {
                pdArea.put("id", portDto.getCityId());
                portDto.setCityName(getCityName(portDto.getCountryId(), portDto.getCityId()));
            }
        }
        QResultDto dto = new QResultDto();
        dto.setData(list);
        dto.setPagination(pd.getPagination());
        return dto;
    }


    @Override
    public List<Port> portFliter(String country, String provinceId, String cityId) {
        Map<String, Object> map = new HashMap<>(16);
        map.put("countryId", country);
        if (!StringUtils.isEmpty(provinceId) && StringUtils.isEmpty(cityId)) {
            ResultDto dto = areaManager.findByParentId(country, provinceId, "", 1, 100);
            List<AreaDto> list = (List<AreaDto>) dto.getData();
            List<String> cityIds = EntityUtils.getStringPropListFromBeans(list, "id");
            map.put("cityIds", cityIds);
        } else {
            map.put("cityIds", Collections.singletonList(cityId));
        }


        // 调用方法查询数据
        return dao.findForList("PortMapper.portFliter", map, Port.class);
    }


    /**
     * 根据条件分页查询港口-端接口
     *
     * @param params params
     * @return ResultDto
     */
    @Override
    public ResultDto findPortShortList(QueryParams params) {
        String language = PrincipalUtils.getLocalLanguage();
        params.setLanguage(language);
        ParamData pd = this.convertQueryParams(params);
        // 调用方法查询数据
        List<PortDto> list = dao.findForList("PortMapper.portShortListPage", pd, PortDto.class);
        QResultDto dto = new QResultDto();
        dto.setData(list);
        dto.setPagination(pd.getPagination());
        return dto;
    }

    /**
     * 根据港口portIds查询港口信息s
     *
     * @param portIds portIds
     * @return List<PortDto>
     */
    @Override
    public List<PortDto> findByPortIds(List<Integer> portIds) {
        Map<String, Object> map = new HashMap<>();
        map.put("list", portIds);
        map.put("language", PrincipalUtils.getLocalLanguage());
        return dao.findForList("PortMapper.findByPortIds", map, PortDto.class);

    }

    @Override
    public ResultDto findCityByCountryCode(String countryId) {

        ParamData pd = new ParamData();
        pd.put("countryId", countryId);
        List<CityModel> list = dao.findForList("PortMapper.findCityByCountryCode", pd, CityModel.class);
        QResultDto dto = new QResultDto();
        dto.setData(list);
        dto.setPagination(pd.getPagination());
        return dto;
    }

    @SuppressWarnings("rawtypes")
    @Override
    public ResultDto findI18nByParam(QueryParams params) {
        ParamData pd = this.convertQueryParams(params);
        List entry = dao.findForList(getSqlName("findI18nByParamListPage"), pd, Map.class);
        QResultDto dto = new QResultDto(entry, pd.getPagination());
        return dto;
    }

    /**
     * 港口编码校验
     *
     * @param code
     * @return
     */
    @Override
    public void checkCode(String code, int id) {
        Map<String, Object> map = new HashMap<>();
        map.put("code", code);
        if (id > 0) {
            map.put("id", id);
        }
        Port portExist = (Port) dao.findForObject("PortMapper.checkCode", map);
        if (portExist != null) {
            throw Exceptions.bizException(ErrorCodes.ERROR_BIZ_PORT_CODE_EXIST);
        }
    }

    /**
     * 港口下拉列表
     *
     * @return ResultDto
     */
    @Override
    public ResultDto shortPortListPage(QueryParams params) {
        String language = PrincipalUtils.getLocalLanguage();
        params.setLanguage(language);
        ParamData pd = this.convertQueryParams(params);
        // 调用方法查询数据
        List<TransportModel> list = dao.findForList("PortMapper" + ".shortPortListPage", pd, TransportModel.class);
        if (list != null) {
            for (TransportModel transportModel : list) {
                Map<String, Object> map = new HashMap<>();
                map.put("language", language);
                map.put("figureCode", transportModel.getContryName());
                AreaDto areaDto = new AreaDto();
                if (!StringUtils.isEmpty(transportModel.getCityId())) {
                    map.put("id", transportModel.getCityId());
                    if (transportModel.getContryName() != null && !"CN".equals(transportModel.getContryName())) {
                        areaDto = (AreaDto) dao.findForObject("AreaMapper" + ".findByAreaId", map);
                    } else {
                        areaDto = (AreaDto) dao.findForObject("AreaCNMapper" + ".findByAreaId", map);
                    }
                    if (!ObjectUtils.isEmpty(areaDto)) {
                        transportModel.setCityName(areaDto.getName());
                    }
                }
                CountryDto countryDto = (CountryDto) dao.findForObject("CountryMapper" + ".findCountryByCode", map);
                if (!ObjectUtils.isEmpty(countryDto)) {
                    transportModel.setContryName(countryDto.getName());

                }
            }
        }
        QResultDto dto = new QResultDto();
        dto.setData(list);
        dto.setPagination(pd.getPagination());
        return dto;
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public int synchroPort(Port port) {
        dao.update("PortMapper.updateByPortId", port);
        return port.getId();
    }


    /**
     * 根据国家和城市查询港口下拉列表
     *
     * @return ResultDto
     */
    @Override
    public ResultDto portDropListPage(QueryParams params) {
        String language = PrincipalUtils.getLocalLanguage();
        params.setLanguage(language);
        ParamData pd = this.convertQueryParams(params);
        // 调用方法查询数据
        List<TransportModel> list = dao.findForList("PortMapper" + ".portDropListPage", pd, TransportModel.class);
        if (list != null) {
            for (TransportModel transportModel : list) {
                Map<String, Object> map = new HashMap<>();
                map.put("language", language);
                map.put("figureCode", transportModel.getContryId());
                AreaDto areaDto = new AreaDto();
                if (!StringUtils.isEmpty(transportModel.getCityId())) {
                    map.put("id", transportModel.getCityId());
                    if (transportModel.getContryId() != null && !"CN".equals(transportModel.getContryId())) {
                        areaDto = (AreaDto) dao.findForObject("AreaMapper" + ".findByAreaId", map);
                    } else {
                        areaDto = (AreaDto) dao.findForObject("AreaCNMapper" + ".findByAreaId", map);
                    }
                    if (!ObjectUtils.isEmpty(areaDto)) {
                        transportModel.setCityName(areaDto.getName());
                    }

                }
                CountryDto countryDto = (CountryDto) dao.findForObject("CountryMapper" + ".findCountryByCode", map);
                if (!ObjectUtils.isEmpty(countryDto)) {
                    transportModel.setContryName(countryDto.getName());

                }
            }
        }
        QResultDto dto = new QResultDto();
        dto.setData(list);
        dto.setPagination(pd.getPagination());
        return dto;
    }

    /**
     * 按英文名称或名称来精确匹配需要的港口信息
     *
     * @param name 中文或英文名称
     * @return 港口信息
     */
    @Override
    public List<Port> findPortByName(String name,String countryId) {
        List<Port> portLst = null;
        if (!StringUtils.isEmpty(name)) {
            ParamData pd = new ParamData();
            pd.put("countryId", countryId);
            pd.put("name", name);
            portLst = dao.findForList("PortMapper" + ".findPortByName", pd,Port.class);
        }
        return portLst;
    }


    @Override
    protected String getMapperNamespace() {
        return "PortMapper";
    }
}
